test(remote): cover the phone projection on a REAL v3 workspace - #1065
Merged
Merged
Conversation
#1031 item 4. Every phone-projection test built a v2 document by hand — `tabs[]` with a `root` tile tree — so nothing in the suite exercised the shape the app has actually been persisting since #1013 migrated to the unified stage. The projection DOES handle v3, but a regression in that half would have been silent, and the phone's entire session list depends on it. The proof that this was a real blind spot rather than a tidiness exercise: deleting the v3 project parsing from `agentActivity/workspaceProjection.ts` leaves the existing phone suite completely GREEN (4 passed) and fails only the new file. Ignoring the row's own `projectId` — the v3 membership rule — does the same. The input is the real `~/.config/agent-code/workspace.json` the app wrote on 2026-09-20: one window, three projects, 13 sessions across five provider kinds. Sanitized under the same contract as the v2 fixture — structure and every value unchanged except `cwd`, `title` and `projectTabTitle`, each mapped one-to-one so equal values stay equal — and verified afterwards to contain no absolute home path, username or real directory name. Each test guards against being vacuous: the first asserts the fixture really is v3 with no `tabs` to fall back on, the membership test asserts the file actually places sessions in more than one project, and the identity test asserts four or more provider kinds are represented. The v2 test file is deliberately left alone rather than parameterised: main reads whatever is on disk, and a window that has not saved since the upgrade still holds a v2 document. Both generations must keep working, so both keep their own evidence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review of #1065. The most important finding is that my own justification was false, so it is corrected rather than softened. `agentActivity/workspaceProjection.test.ts` already covers the SHARED decoder on v3 documents, and deleting the v3 `projects` parsing fails two of its tests. I ran that mutation only against `src/main/remote/`, saw it green, and generalised it into "a regression would have been silent". It would not have been. The real gap is narrower and specific to the phone: nothing drove `RemoteWorkspaceProjection` with a v3 document at all. The header, the README and the PR now say that instead. The identity test asserted only `kind` and `cwd`, both pass-throughs. It now asserts `tldrIdentity` — the key the remote server joins every TLDR and Goal frame on, so dropping it silently empties both on the phone while the session list still looks right. Nulling it now fails 2. The re-projection test changes a `tldrIdentity` rather than a `title` for the same reason: that equality check was unpinned, and removing it left all 74 remote tests green. It now fails 1. The kind count said "four or more" under a comment naming five; it says five. The sanitization table was wrong in three ways: it listed `projectTabTitle`, which is v2-only and appears in neither file; it omitted `projects[].title`, which carries three of the placeholders; and it said nothing about `drafts`, which persists RAW COMPOSER TEXT. This capture contained none, so the file is clean — but clean by timing, not by process, and the README now says to drop `drafts` unconditionally when re-capturing. `/fixture/project-N` named directories, not projects — two of them are different directories inside one project, so the numbering never tracked `Title N`. They are `/fixture/dir-N`. The store fake was duplicated verbatim across both projection test files; one definition of "the store notifies only after bytes reach disk" now lives in `workspaceProjection.testSupport.ts`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The extracted helper declared a mutable PersistedWindow[][], which the v2 file's own readonly saves could not satisfy. Caught by tsc after the previous commit was already pushed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Juliusolsson05
added a commit
that referenced
this pull request
Sep 20, 2026
…ght real bugs Two of the three were my own: #1067's first fix re-created the #1021 input trap, and #1065's stated justification was false. Both are recorded as such rather than as generic review findings, because the pattern worth remembering is that I generalised from a mutation run against too narrow a suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1031 item 4.
What was actually missing — and what was not
Correction to this PR's original claim. I first wrote that nothing exercised v3 and that a regression "would have been silent". That is false, and the review caught it:
agentActivity/workspaceProjection.test.tsalready has aprojectWorkspace — v3 documents (#992)block, and deleting the v3projectsparsing fails two of its tests. I had run that mutation only againstsrc/main/remote/, seen it green, and generalised.The real gap is narrower and specific to the phone: nothing drove
RemoteWorkspaceProjection— the phone's own read model — with a v3 document at all. Every test in that file built a v2tabs[]/roottile tree by hand, which is not what the app has persisted since #1013. That class is what the phone's entire session list depends on.The fixture
The real
~/.config/agent-code/workspace.jsonfrom 2026-09-20: one window, 3 projects, 13 sessions across five provider kinds.The review audited every string in it and found nothing to redact. Two things are worth stating rather than leaving implicit:
draftspersists raw composer text. This capture contained none, so the file is clean — but clean by timing, not by process. The README now says to dropdraftsunconditionally when re-capturing.tldrIdentity,providerSessionId, tmux names) because the tests join on them and they are inert without the transcript files they key into. If a debug bundle or proxy dump were ever published from the same machine they would become a correlation key — the known trade, and the same one the existing v2 owner fixture makes.cwdplaceholders are/fixture/dir-N, notproject-N: two of them are different directories inside one project, so the numbering never trackedTitle N.What the tests pin
The identity test originally asserted only
kindandcwd— both pass-throughs. It now assertstldrIdentity, the key the remote server joins every TLDR and Goal frame on: dropping it silently empties both on the phone while the session list still looks correct.tldrIdentityin the shared projectiontldrIdentityequality check inworkspaceProjection.tsprojectsparsingagentActivity(as it always did)Each test also guards its own premise: the fixture really is v3 with no
tabsto fall back on, it places sessions in more than one project, and five provider kinds are represented.The store fake was duplicated verbatim across both projection test files; one definition now lives in
workspaceProjection.testSupport.ts.npx tsc -bclean;src/main/remote/green (10 files / 74 tests).🤖 Generated with Claude Code